/*
* Global variable definition
*/

#include "../inc/config.h"


int thread_amount = 0; 
enum debug_type debug = NONE;

const char *keywords[] = {
    "auto",       "break",  "case",    "char",     "const",    "continue",
    "default",    "do",     "double",  "else",     "enum",     "extern",
    "float",      "for",    "goto",    "if",       "int",      "long",
    "register",   "return", "short",   "signed",   "sizeof",   "static",
    "struct",     "switch", "typedef", "union",    "unsigned", "void",
    "volatile",   "while",  "inline",  "restrict", "_Bool",    "_Complex",
    "_Imaginary", "asm",    "fortran"};

const char *preprocess[] = {
    "#include", "#define", "#undef", "#if",   "#ifdef",  "#ifndef", "#else",
    "#elif",    "#endif",  "#error", "#line", "#pragma", "#warning"};

const char *single_operator[] = {"+",  "-",  "*",  "/",  "<",  ">",  "=",
                           "&",  "|",  "%",  "~", "^", "?", ":", ".",  "!",};

const char *delimiter[] = {"(", ")", "[", "]", "{", "}", ";", ","};

/* setting the thread num */
void set_thread_num(int n){
  thread_amount = n;
}

/* getting the thread num */
int get_thread_num(){
  return thread_amount;
}

/* getting the debug type */
enum debug_type get_debug(){
  return debug;
}

/* getting string type of the debug type */
char * get_debug_type(enum debug_type type){
  switch(type){
    case NONE:
      return "none";
    case INFO:
      return "info";
    case FATAL:
      return "fatal";
    default:
      return "debug";
  }
}

/* setting the debug type */
void set_debug(enum debug_type type){
  debug = type;
}

/* getting the size of keywords */
int get_keywords_size(){
  return sizeof(keywords) / sizeof(keywords[0]);
}

/* getting the size of preprocess */
int get_preprocess_size(){
  return sizeof(preprocess) / sizeof(preprocess[0]);
}

/* getting the size of operator */
int get_single_operator_size(){
  return sizeof(single_operator) / sizeof(single_operator[0]);
}

/* getting the size of delimiter */
int get_delimiter_size(){
 return sizeof(delimiter) / sizeof(delimiter[0]);
}

/* getting the display color of symbol */
char* get_symbol_color(enum symbol_type type) {
  switch (type) {
  case KEYWORDS:
  case PREPROCESS:
    return RED;
  case COMMENT:
    return GRAY;
  case DELIMITER:
    return BLUE;
  case IDENTIFIER:
    return GREEN;
  case OPERATOR:
    return PURPLE;
  case CONST_INT:
  case CONST_INT_U: 
  case CONST_INT_L:
  case CONST_INT_UL:
  case CONST_INT_LL:
  case CONST_INT_ULL:
  case CONST_INT_OCTAL:
  case CONST_INT_HEX:
  case CONST_INT_BIN:
  case CONST_FLOAT:
  case CONST_FLOAT_EXP:
  case CONST_CHAR:
  case CONST_SYMBOL:
  case CONST_ENUM: 
  case CONST_BOOL:
  case CONST_NULL:
    return CYAN;
  case CONST_STR:
  case HEADER:
    return YELLOW;
  default:
    return NORMAL_COLOR;
  }
}

/* getting the color of symbol on html */
char* get_symbol_html_color(enum symbol_type type, enum symbol_type next_type) {
  switch (type) {
  case UNRECOGNIZED:
    return "P12";
  case KEYWORDS:
  case PREPROCESS:
    return "p1";
  case COMMENT:
    return "p2";
  case DELIMITER:
    return "p3";
  case IDENTIFIER:
    if(next_type == FUNCTION) return "p10";
    else return "p4";
  case OPERATOR:
    return "p5";
  case CONST_INT:
  case CONST_INT_U: 
  case CONST_INT_L:
  case CONST_INT_UL:
  case CONST_INT_LL:
  case CONST_INT_ULL:
  case CONST_INT_OCTAL:
  case CONST_INT_HEX:
  case CONST_INT_BIN:
  case CONST_FLOAT:
  case CONST_FLOAT_EXP:
    return "p6";
  case CONST_CHAR:
  case CONST_SYMBOL:
  case CONST_ENUM: 
    return "p7";
  case CONST_BOOL:
  case CONST_NULL:
    return "p8";
  case CONST_STR:
  case HEADER:
    return "p9";
  case FUNCTION:
    return "p10";
  case BACKSLASH:
    return "p3";
  default:
    return "p11";
  }
}

/* getting the string type of symbol type */
char* get_symbol_type(enum symbol_type type) {
  switch (type) {
  case UNRECOGNIZED:
    return "UNRECOGNIZED";
  case KEYWORDS:
    return "KEYWORDS";
  case PREPROCESS:
    return "PREPROCESS";
  case COMMENT:
    return "COMMENT";
  case DELIMITER:
    return "DELIMITER";
  case IDENTIFIER:
    return "IDENTIFIER";
  case OPERATOR:
    return "OPERATOR";
  case CONST_INT:
    return "CONST_INT";
  case CONST_INT_U: 
    return "CONST_INT_U";
  case CONST_INT_L:
    return "CONST_INT_L";
  case CONST_INT_UL:
    return "CONST_INT_UL";
  case CONST_INT_LL:
    return "CONST_INT_LL";
  case CONST_INT_ULL:
    return "CONST_INT_ULL";
  case CONST_INT_OCTAL:
    return "CONST_INT_OCTAL";
  case CONST_INT_HEX:
    return "CONST_INT_HEX";
  case CONST_INT_BIN:
    return "CONST_INT_BIN";
  case CONST_FLOAT:
    return "CONST_FLOAT";
  case CONST_FLOAT_EXP:
    return "CONST_FLOAT_EXP";
  case CONST_CHAR:
    return "CONST_CHAR";
  case CONST_SYMBOL:
    return "CONST_SYMBOL";
  case CONST_ENUM: 
    return "CONST_ENUM";
  case CONST_BOOL:
    return "CONST_BOOL";
  case CONST_NULL:
    return "CONST_NULL";
  case CONST_STR:
    return "CONST_STR";
  case HEADER:
    return "HEADER";
  case FUNCTION:
    return "FUNCTION";
  case BACKSLASH:
    return "BACKSLASH";
  case MACRO:
    return "MACRO";
  case ERROR:
    return "ERROR";
  case FILE_EOF:
    return "FILE_EOF";
  default:
  return "UNRECOGNIZED";
  }
}